package com.jfinal.ext.ueditor.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.aop.AopManager;
import com.jfinal.core.JFinal;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.StrKit;
import org.jetbrains.annotations.NotNull;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Timor
 * @version 1.0
 * @date 2023/01/04 18:22:38
 */
public class UeditorConfig {
    public static final String NAME = "name";

    public static final String FILE = "file";
    public static final String VIDEO = "video";
    public static final String AUDIO = "audio";

    public static final String IMAGE = "image";
    public static final String SCRAWL = "scrawl";
    /**
    public static final String SCREENSHOT = "screenshot";
    public static final String SNAP_SCREEN = "snapscreen";
    */
    public static final String SCREENSHOT = "snapscreen";
    public static final String CATCHER = "catcher";

    public static final String FORMULA_CONFIG = "formulaConfig";
    public static final String IMAGE_MANAGER = "imageManager";
    public static final String FILE_MANAGER = "fileManager";

    private static final List<String> KEYS = List.of(
            FILE_MANAGER, IMAGE_MANAGER,
            FILE, VIDEO, AUDIO,
            IMAGE, SCRAWL, SCREENSHOT, CATCHER
    );

    private FileUploadConfig fileUploadConfig;
    private FileUploadConfig videoUploadConfig;
    private FileUploadConfig audioUploadConfig;

    private ImageUploadConfig imageUploadConfig;
    private ImageUploadConfig scrawlUploadConfig;
    private ImageUploadConfig screenshotUploadConfig;
    private CatchImageConfig catcherUploadConfig;

    private FileManagerConfig fileManagerConfig;
    private ImageManagerConfig imageManagerConfig;

    private FormulaConfig formulaConfig;


    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


    public static void init(@NotNull String configFile) throws IOException {
        try (final InputStream is = JFinal.class.getClassLoader().getResourceAsStream(configFile)) {
            if (null != is) {
                final String config = new String(is.readAllBytes());

                AopManager.me().addSingletonObject(UeditorConfig.by(config));
            } else {
                throw new FileNotFoundException("文件不存在：" + configFile);
            }
        }
    }

    public static UeditorConfig by(String config) {
        // 删除注释
        final String temp = config.replaceAll("/\\*(\\s|.)*?\\*/", "");

        return by(JSON.parseObject(temp));
    }

    public static UeditorConfig by(JSONObject json) {
        final UeditorConfig config = new UeditorConfig();

        config.formulaConfig = json.getObject(FORMULA_CONFIG, FormulaConfig.class);


        final JSONObject temp = new JSONObject();

        KEYS.forEach(item -> {
            final JSONObject object = new JSONObject();

            object.put(NAME, item);

            temp.put(item, object);
        });

        json.forEach((key, value) -> {
            for (String item : KEYS) {
                if (key.startsWith(item)) {
                    final String attr = key.substring(item.length());
                    // try put(firstCharToLowerCase(attr), value)
                    temp.getJSONObject(item).put(attr, value);
                    break;
                }
            }
        });


        config.fileUploadConfig = temp.getObject(FILE, FileUploadConfig.class);
        config.videoUploadConfig = temp.getObject(VIDEO, FileUploadConfig.class);
        config.audioUploadConfig = temp.getObject(AUDIO, FileUploadConfig.class);

        config.imageUploadConfig = temp.getObject(IMAGE, ImageUploadConfig.class);
        config.scrawlUploadConfig = temp.getObject(SCRAWL, ImageUploadConfig.class);
        config.screenshotUploadConfig = temp.getObject(SCREENSHOT, ImageUploadConfig.class);
        config.catcherUploadConfig = temp.getObject(CATCHER, CatchImageConfig.class);

        config.fileManagerConfig = temp.getObject(FILE_MANAGER, FileManagerConfig.class);
        config.imageManagerConfig = temp.getObject(IMAGE_MANAGER, ImageManagerConfig.class);

        return config;
    }


    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


    public String toJsonString() {
        final JSONObject json = new JSONObject();

        json.put(FILE, JSON.toJSON(fileUploadConfig));
        json.put(VIDEO, JSON.toJSON(videoUploadConfig));
        json.put(AUDIO, JSON.toJSON(audioUploadConfig));

        json.put(IMAGE, JSON.toJSON(imageUploadConfig));
        json.put(SCRAWL, JSON.toJSON(scrawlUploadConfig));
        json.put(SCREENSHOT, JSON.toJSON(screenshotUploadConfig));
        json.put(CATCHER, JSON.toJSON(catcherUploadConfig));

        json.put(FILE_MANAGER, JSON.toJSON(fileManagerConfig));
        json.put(IMAGE_MANAGER, JSON.toJSON(imageManagerConfig));


        final Map<String, Object> config = new HashMap<>(KEYS.size());

        config.put(FORMULA_CONFIG, formulaConfig);

        json.forEach((key, obj) -> {
            final JSONObject item = (JSONObject) obj;

            item.forEach((attr, value) -> {
                String configKey = key + StrKit.firstCharToUpperCase(attr);

                config.put(configKey, value);
            });
        });

        return JsonKit.toJson(config);
    }

    public IActionConfig getActionConfig(@NotNull String key) {
        return switch (key) {
            case FILE_MANAGER -> fileManagerConfig;
            case IMAGE_MANAGER -> imageManagerConfig;

//            case FORMULA_CONFIG -> formulaConfig;
            default -> getUploadConfig(key);
        };
    }

    public IUploadConfig getUploadConfig(@NotNull String key) {
        return switch (key) {
            case FILE -> fileUploadConfig;
            case VIDEO -> videoUploadConfig;
            case AUDIO -> audioUploadConfig;

            case IMAGE -> imageUploadConfig;
            case SCRAWL -> scrawlUploadConfig;
            case SCREENSHOT -> screenshotUploadConfig;
            case CATCHER -> catcherUploadConfig;

            default -> null;
        };
    }


    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


    public FileUploadConfig getFileUploadConfig() {
        return fileUploadConfig;
    }

    public FileUploadConfig getVideoUploadConfig() {
        return videoUploadConfig;
    }

    public FileUploadConfig getAudioUploadConfig() {
        return audioUploadConfig;
    }

    public ImageUploadConfig getImageUploadConfig() {
        return imageUploadConfig;
    }

    public ImageUploadConfig getScrawlUploadConfig() {
        return scrawlUploadConfig;
    }

    public ImageUploadConfig getScreenshotUploadConfig() {
        return screenshotUploadConfig;
    }

    public CatchImageConfig getCatcherUploadConfig() {
        return catcherUploadConfig;
    }

    public FileManagerConfig getFileManagerConfig() {
        return fileManagerConfig;
    }

    public ImageManagerConfig getImageManagerConfig() {
        return imageManagerConfig;
    }

    public FormulaConfig getFormulaConfig() {
        return formulaConfig;
    }
}
